package ddns

import (
	"encoding/json"
	"gitee.com/yysf-xin/dproxy/pkg/tools"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	openapiutil "github.com/alibabacloud-go/openapi-util/service"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/go-chi/chi/v5"
	"net"
	"net/http"
	"net/http/httputil"
	"strings"
)

type AliYun struct {
	*openapi.Client
}

func (a *AliYun) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	_, _ = httputil.DumpRequest(r, true)
}

func NewAliYun(cfg *Config) (a *AliYun, err error) {
	client, err := CreateClient(tea.String(cfg.AccessKey), tea.String(cfg.AccessSecret))
	if err != nil {
		return nil, err
	}
	a = &AliYun{client}
	return
}
func (a *AliYun) initRouter(v chi.Router) {
	v.Handle("/aliyun", a)
}

func (a *AliYun) RefreshIP(domain string, _ip net.IP) (err error) {
	ip := _ip.String()
	queries := make(map[string]interface{})
	queries["InputString"] = tea.String(domain)

	result, err := a.call(getMainDomainName(), queries)
	if err != nil {
		return
	}
	domainName := result["DomainName"].(string)
	subDomain := domain[:len(domain)-len(domainName)-1]
	queries = map[string]interface{}{}
	queries["DomainName"] = domainName
	queries["RRKeyWord"] = subDomain
	if strings.Contains(ip, ":") {
		queries["Type"] = "AAAA"
	} else {
		queries["Type"] = "A"
	}
	result, err = a.call(createParam("DescribeDomainRecords"), queries)
	if err != nil {
		tools.Log.Println("describe domain err", err)
		return
	}
	queries["RR"] = subDomain
	queries["Value"] = tea.String(ip)
	delete(queries, "RRKeyWord")

	total, _ := result["TotalCount"].(json.Number).Int64()

	if total == 0 {
		result, err = a.call(createParam("AddDomainRecord"), queries)
		if err != nil {
			tools.Log.Println("add domain err", err)
			return
		}
	} else {
		records := result["DomainRecords"].(map[string]interface{})
		record := records["Record"].([]interface{})
		if record == nil || len(record) == 0 {
			return
		}

		for _, v := range record {
			queries["RecordId"] = v.(map[string]interface{})["RecordId"]
			result, err = a.call(createParam("UpdateDomainRecord"), queries)
			if err != nil {
				if sdkErr, ok := err.(*tea.SDKError); ok {
					if *sdkErr.Code == "DomainRecordDuplicate" {
						err = nil
					}
				}
			}
		}
	}
	return
}

/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */

func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *openapi.Client, _err error) {
	config := &openapi.Config{
		// 必填，您的 AccessKey ID
		AccessKeyId: accessKeyId,
		// 必填，您的 AccessKey Secret
		AccessKeySecret: accessKeySecret,
	}
	// 访问的域名
	config.Endpoint = tea.String("alidns.cn-hangzhou.aliyuncs.com")
	_result = &openapi.Client{}
	_result, _err = openapi.NewClient(config)
	return _result, _err
}

// CreateApiInfo
/**
 * API 相关
 * @param path params
 * @return OpenApi.Params
 */
func updateDomainRecord() *openapi.Params {
	return createParam("UpdateDomainRecord")
}
func (a *AliYun) call(params *openapi.Params, queries map[string]interface{}) (result map[string]interface{}, err error) {
	runtime := &util.RuntimeOptions{}
	request := &openapi.OpenApiRequest{
		Query: openapiutil.Query(queries),
	}
	result, err = a.CallApi(params, request, runtime)
	if err == nil {
		result = result["body"].(map[string]interface{})
	}
	return
}

func getMainDomainName() *openapi.Params {
	return createParam("GetMainDomainName")
}
func createParam(action string) (_result *openapi.Params) {
	params := &openapi.Params{
		// 接口名称
		Action: tea.String(action),
		// 接口版本
		Version: tea.String("2015-01-09"),
		// 接口协议
		Protocol: tea.String("HTTPS"),
		// 接口 HTTP 方法
		Method:   tea.String("POST"),
		AuthType: tea.String("AK"),
		Style:    tea.String("RPC"),
		// 接口 PATH
		Pathname: tea.String("/"),
		// 接口请求体内容格式
		ReqBodyType: tea.String("json"),
		// 接口响应体内容格式
		BodyType: tea.String("json"),
	}
	_result = params
	return _result
}
